/*
 * Created by Jaren at 2021/10/28 10:23
 */
import 'dart:typed_data';

import 'package:binary/src/boxed_int.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/euc/euc_settings.dart';
import 'package:inmotion_protocol/lorin/constant.dart';
import 'package:inmotion_protocol/util/byte_util.dart';
import 'package:inmotion_protocol/util/version.dart';

class V11Settings extends EucSettings {
  Uint8 decorativeLightMode = Uint8.zero; // 装饰灯模式
  Uint8 autoLightLowThr = Uint8.zero; // 照明灯开启的光照强度阈值，单位1%
  Uint8 autoLightHighThr = Uint8.zero; // 照明灯关闭的光照强度阈值，单位1%
  Uint8 lightBrightness = Uint8.zero; // 手动设置的照明灯亮度，单位1%

  /// DRL开关, 使用decorativeLightState
  Uint4 drlState = Uint4.zero;
  Uint4 decorativeLightState = Uint4.zero; // 装饰灯开关

  Uint4 autoLightState = Uint4.zero; // 照明灯自动开关
  Uint4 autoLightBrightnessState = Uint4.zero; // 照明灯亮度自动调节功能开关

  Uint4 fanQuietMode = Uint4.zero; // 风扇静音模式

  Uint4 fanState = Uint4.zero;

  V11Settings(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    if (model.isV11Y()) {
      compact = _V11YSettingsDefault();
    } else {
      String hmicVersion = version.getAppVersionByDevice(Constant.deviceEUCV11HMIC);
      if (VersionUtils.higherOrEquals(hmicVersion, VersionConstant.v11Hmic1228)) {
        compact = _V11SettingsV137();
        return;
      }
      compact = _V11SettingsDefault();
    }
  }

  @override
  String toString() {
    return 'V11Settings{driveMode: $driveMode, pitchAngleZero: $pitchAngleZero, comfortableDriveModePedalSensitivity: $comfortableDriveModePedalSensitivity, '
        'classicDriveModePedalSensitivity: $classicDriveModePedalSensitivity, ridingMode: $ridingMode, volume: $volume, standbyTime: $standbyTime,'
        ' decorativeLightMode: $decorativeLightMode, autoLightLowThr: $autoLightLowThr, autoLightHighThr: $autoLightHighThr, '
        'lightBrightness: $lightBrightness, speedingFeedback: $speedingFeedback, brakingFeedback: $brakingFeedback, decorativeLightState: $decorativeLightState, '
        'liftedState: $liftedState, autoLightState: $autoLightState, autoLightBrightnessState: $autoLightBrightnessState, lockState: $lockState, '
        'transportModeState: $transportModeState, loadDetect: $loadDetect, noLoadDetect: $noLoadDetect, lowBatteryMode: $lowBatteryMode, '
        'lowBatterySafeMode: $lowBatterySafeMode, fanQuietMode: $fanQuietMode, soundWave: $soundWave, usbPower: $usbPower, '
        'remainderRangeEstimate: $remainderRangeEstimate, assistBalance: $assistBalance, speedingBrakingFeedbackState: $speedingBrakingFeedbackState}';
  }
}

class _V11SettingsV137 extends Compact<V11Settings> {
  @override
  void fromBytes(V11Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.limitSpeed = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.pitchAngleZero = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.driveMode = ByteUtil.bitValue(bytes[offset], 0, 4);
    output.ridingMode = ByteUtil.bitValue(bytes[offset], 4, 4);
    offset++;
    output.comfortableDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.classicDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.volume = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.soundPackId = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.standbyTime = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.decorativeLightMode = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightLowThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightHighThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.speedingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.brakingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    output.soundState = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.drlState = output.decorativeLightState;
    output.liftedState = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.autoLightState = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    output.autoLightBrightnessState = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.lockState = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.transportModeState = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.loadDetect = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    output.noLoadDetect = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.lowBatterySafeMode = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.fanQuietMode = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.soundWave = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    // 2bit reverse for touch key
    output.usbPower = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.remainderRangeEstimate = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.assistBalance = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    output.speedingBrakingFeedbackState = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    // 剩余保留
  }

  @override
  int length() {
    return 28;
  }
}

class _V11SettingsDefault extends Compact<V11Settings> {
  @override
  void fromBytes(V11Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.limitSpeed = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.pitchAngleZero = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.driveMode = ByteUtil.bitValue(bytes[offset], 0, 4);
    output.ridingMode = ByteUtil.bitValue(bytes[offset], 4, 4);
    offset++;
    output.comfortableDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.classicDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.volume = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.soundPackId = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.standbyTime = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.decorativeLightMode = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightLowThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightHighThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.speedingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.brakingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    output.soundState = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.drlState = output.decorativeLightState;
    output.liftedState = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.autoLightState = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    output.autoLightBrightnessState = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.lockState = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.transportModeState = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.loadDetect = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    output.noLoadDetect = ByteUtil.bitValue(bytes[offset], 0, 2); // 2bit
    output.lowBatteryMode = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.fanQuietMode = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    output.soundWave = ByteUtil.bitValue(bytes[offset], 6, 2); // 2bit
    offset++;
    // 2bit reverse for touch key
    output.usbPower = ByteUtil.bitValue(bytes[offset], 2, 2); // 2bit
    output.remainderRangeEstimate = ByteUtil.bitValue(bytes[offset], 4, 2); // 2bit
    // 剩余保留
  }

  @override
  int length() {
    return 24;
  }
}

class _V11YSettingsDefault extends Compact<V11Settings> {
  @override
  void fromBytes(V11Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.limitSpeed = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    // 跳过overSpeedWarningThr(2byte) + overOutputTiltBackThr(2byte) + overOutputWarningThr(2byte) +
    offset += 2;
    offset += 2;
    offset += 2;

    output.pitchAngleZero = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.driveMode = ByteUtil.bitValue(bytes[offset], 0, 4);
    output.ridingMode = ByteUtil.bitValue(bytes[offset], 4, 4);
    offset++;
    output.comfortableDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.classicDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    output.speedingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.brakingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.volume = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.soundPackId = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.standbyTime = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    // 跳过lightEffectMode(1byte)
    offset++;
    output.autoLightLowThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightHighThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    // 跳过maxChargeBatteryLevel(1byte) + maxDcOutputBatteryLevel(1byte)
    offset++;
    offset++;

    // 保留2byte
    offset += 2;

    output.soundState = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.drlState = output.decorativeLightState;
    output.liftedState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.autoLightState = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.autoLightBrightnessState = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.lockState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.transportModeState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.loadDetect = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.noLoadDetect = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.lowBatterySafeMode = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.fanQuietMode = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.soundWave = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    // 跳过2bit touch key
    output.usbPower = ByteUtil.bitValue(bytes[offset], 2, 4);
    output.remainderRangeEstimate = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.assistBalance = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.speedingBrakingFeedbackState = ByteUtil.bitValue(bytes[offset], 2, 2);
    // 其余保留
  }

  @override
  int length() {
    return 38;
  }
}
